﻿using OSGeo.GDAL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TileMap
{
    public partial class Form1 : Form, IMapTileFilter
    {
        public Form1()
        {
            InitializeComponent();
            using (var g = CreateGraphics())
            {
                bkimage = new Bitmap(ImageWidth, ImageHeight, g);
                graphics = Graphics.FromImage(bkimage);
                graphics.Clear(BackColor);
                BackgroundImage = bkimage;
            }
            this.DoubleBuffered = true;
        }

        private readonly int ImageWidth = 1920;
        private readonly int ImageHeight = 1080;
        private Image bkimage;
        private Graphics graphics;

        public int ColumnCount { get; set; }
        public int RowCount { get; set; }

        private void W2TButton_Click(object sender, EventArgs e)
        {
            try
            {
                //var c = new MapPosCalc();
                //var res = c.WorldToTilePos(
                //    double.Parse(lonTextBox.Text),
                //    double.Parse(latTextBox.Text),
                //    int.Parse(zoomTextBox.Text));
                //xLabel.Text = res.X.ToString();
                //yLabel.Text = res.Y.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void T2WButton_Click(object sender, EventArgs e)
        {
            //Vector2D v = new Vector2D() { X = 12848758.7066248, Y = 5022830.00267544 };

            //try
            //{
            //    var c = new MapPosCalc();
            //    var lot = c.Mercator2lonLat(v);
            //    var res = c.TileToWorldPos(
            //        double.Parse(tileXTextBox.Text),
            //        double.Parse(tileYTextBox.Text),
            //        int.Parse(t2wZoomTextBox.Text));
            //    lonLabel.Text = res.X.ToString();
            //    LatLabel.Text = res.Y.ToString();
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message);
            //}
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //TestReadTiff();

            //TestDownCellMap();

            //TestJsonConfig();

            //graphics.Clear(Color.DarkBlue);
            //this.Refresh();
            CoordTransform coord = new CoordTransform();
            var cc = coord.Wgs84ToGcj02(new Coordinate(102.0, 34.0));



            int i = 0;

        }

        private static void TestJsonConfig()
        {
            TileMapData data = new TileMapData()
            {
                Left = 11,
                Right = 12,
                Top = 13,
                Bottom = 14,

                CellColumnCount = 2,
                CellRowCount = 3,

                CellHeight = 200,
                CellWidth = 300,

                CellDatas = new TileMapCellData[3, 2]
            };
            for (int c = 0; c < data.CellColumnCount; ++c)
            {
                for (int r = 0; r < data.CellRowCount; ++r)
                {
                    data.CellDatas[r, c] = new TileMapCellData()
                    {
                        Left = 100,
                        Right = 110,
                        Top = 120,
                        Bottom = 140,
                        HeightMapFileName = "PP",
                        TextureFileName = "OO",
                        MaxHeight = 100,
                        MinHeight = 50
                    };
                }
            }

            data.SaveJson("save.json");

            var rr = TileMapData.LoadJson("save.json");
        }

        private static void TestReadTiff()
        {
            Gdal.AllRegister();
            Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                var dataset = Gdal.Open(dlg.FileName, Access.GA_ReadOnly);
            }
        }

        private void TestDownCellMap()
        {
            int column = 3284;
            int row = 2465;
            int zoom = 12;

            new MapCellDown()
            {
                Column = column,
                Row = row,
                Zoom = zoom
            }.GetImageAsync(this);
            new MapCellDown()
            {
                Column = 3285,
                Row = 2465,
                Zoom = 12
            }.GetImageAsync(this);

            var res = MapPosCalc.TileToWorldPos(new Point(column, row), zoom);

            var ss = MapPosCalc.WorldToTilePos(res, 12);

            var t = TencentMapTileCalc.TileToWorldPos(new Point(column, row), zoom);

            var tw = TencentMapTileCalc.WorldToTilePos(t, 12);
        }

        public void Filter(Image image, int row, int column)
        {
            if (graphics != null && image != null)
            {
                int width = ImageWidth / ColumnCount;
                int height = ImageHeight / RowCount;
                int x = column * width;
                int y = (RowCount - row - 1) * height;

                lock (graphics)
                {
                    graphics.DrawImage(image, x, y, width, height);
                }

                this.BeginInvoke(new CrossAppDomainDelegate(() => Refresh()));
            }
        }

        private async void downloadButton_Click(object sender, EventArgs e)
        {
            downloadButton.Enabled = false;

            double top = double.Parse(topTextBox.Text);
            double bottom = double.Parse(bottomTextBox.Text);
            double left = double.Parse(leftTextBox.Text);
            double right = double.Parse(rightTextBox.Text);

            int zoom = int.Parse(zoomAreaTextBox.Text);

            await Task.Run(() =>
            {
                var res = TileMapDownloader.DownLoad(left, right, top, bottom, zoom, this);

                HeightMapDownLoader.DownLoad(res);

                if (res != null)
                {
                    res.SaveJson("TileMapData.json");
                    MessageBox.Show("Download Completed!");
                }
                TifHeightFile.Clear();
                GC.Collect();
            });

            downloadButton.Enabled = true;

            //var bl = TencentMapTileCalc.WorldToTilePos(new Coordinate()
            //{
            //    Lon = left,
            //    Lat = bottom
            //}, zoom);

            //var tr = TencentMapTileCalc.WorldToTilePos(new Coordinate()
            //{
            //    Lon = right,
            //    Lat = top
            //}, zoom);

            //List<MapCellDown> mapCellDowns = new List<MapCellDown>();

            //for (int c = bl.X; c <= tr.X; ++c)
            //{
            //    for (int r = bl.Y; r <= tr.Y; ++r)
            //    {
            //        mapCellDowns.Add(new MapCellDown()
            //        {
            //            Column = c,
            //            Row = r,
            //            Zoom = zoom
            //        });
            //    }
            //}

            //BasePoint = new Point(bl.X, tr.Y);

            //foreach (var cell in mapCellDowns)
            //{
            //    //cell.GetImageAsync(this);
            //}

            //MapTileSave save = new MapTileSave()
            //{
            //    Column = BasePoint.X,
            //    ColumnCount = 4,
            //    Row = BasePoint.Y,
            //    RowCount = 4,
            //    SaveFileName = "XY.jpg",
            //    MinColumnInChildren = BasePoint.X,
            //    MaxRowInChildren = BasePoint.Y
            //};

            //foreach (var cell in mapCellDowns)
            //{
            //    save.AddCell(cell);
            //}

            //save.GetImageAsync(this);

            //mapCellDowns.Clear();

        }

        private void ClearBackgroung()
        {
            graphics.Clear(BackColor);
            this.Refresh();
        }
    }
}
